%%%-----------------------------------------------------------------------------
%%% @doc
%%% ham server http client
%%%
%%% @end
%%%-----------------------------------------------------------------------------
-module(ham_server_http_client).

-behavior(gen_server).

-include("emqttd.hrl").

-export([start_link/1]).

-export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]).

-record(state, {url,message_queue}).

%%------------------------------------------------------------------------------
%% @doc
%% Start web phone  ets.
%%
%% @end
%%------------------------------------------------------------------------------
start_link(URL) ->
  MODULE = list_to_atom(atom_to_list(?MODULE) ++ URL),
  gen_server2:start_link({local, MODULE}, ?MODULE, [URL], []).

%%%=============================================================================
%%% gen_server callbacks
%%%=============================================================================

init([URL]) ->
  process_flag(trap_exit, true),
  {ok, #state{url = URL,message_queue = queue:new()}}.

handle_call(Request, _From, State) ->
  lager:error("unexpected request: ~p", [Request]),
  {ok, {error, unexpected_request}, State}.


handle_cast({post_request, {Request,Qos}}, State = #state{url = URL,message_queue = Queue}) ->
  lager:debug("Request msg: ~p", [Request]),
  Queue1 = 
    case queue:len(Queue) < ?MAX_QUEUE of 
      true ->
        httpc:request(post,{URL,[],"application/json",unicode:characters_to_binary(Request)},[{timeout,?HTTP_TIMEOUT}],[{sync, false}]),
        case Qos of 
          0 ->
            queue:in({Request,3},Queue);
          _ ->
            queue:in({Request,1},Queue)
        end;    
      false ->
        Queue
    end,
  {noreply, State#state{message_queue = Queue1}};

handle_cast(Msg, State) ->
  lager:error("unexpected msg: ~p", [Msg]),
  {noreply, State}.

handle_info({http, {_, {{_,ReturnCode,_},_,Body}}}, State = #state{url = URL,message_queue = Queue}) ->
  lager:debug("ReturnCode msg: ~p Body msg : ~p~n", [ReturnCode,Body]),
  NewQueue =
    case ReturnCode =:= 200 of 
        true ->
          {_,Queue1} = queue:out(Queue),
          Queue1;
        false -> 
          {{value,{Request,Len}},Queue1} = queue:out(Queue),
          Queue2 = 
            case Len =< 3 of
                true ->
                  Queue3 = queue:in({Request,Len+1},Queue1),
                  httpc:request(post,{URL,[],"application/json",unicode:characters_to_binary(Request)},[{timeout,?HTTP_TIMEOUT}],[{sync, false}]),
                  Queue3;
                _ ->
                  Queue1
            end,
          Queue2      
    end,   
  {noreply,State#state{message_queue = NewQueue}};

handle_info({http, {_, {error,_}}}, State = #state{url = URL,message_queue = Queue}) ->
  {{value,{Request,Len}},Queue1} = queue:out(Queue),
  NewQueue = 
    case Len =< 3 of
        true ->
          Queue2 = queue:in({Request,Len+1},Queue1),
          httpc:request(post,{URL,[],"application/json",unicode:characters_to_binary(Request)},[{timeout,?HTTP_TIMEOUT}],[{sync, false}]),
          Queue2;
        _ ->
          Queue1
    end,
  {noreply,State#state{message_queue = NewQueue}};

handle_info(Info, State) ->
  lager:error("unexpected info: ~p", [Info]),
  {noreply, State}.

terminate(_Reason, _State) ->
  ok.

code_change(_OldVsn, State, _Extra) ->
  {ok, State}.


